#ifndef SCHEDULER_H
#define SCHEDULER_H

using namespace std;

struct SchedulerReturn {
 int return_code;
 int priority;
 int pid;
 char file_name [256];
 int start_time;
 int cycles_completed;

  union Vals {
    // For creating new processes
    struct NewProcess {
      int priority;
      int pid;
      char file_name [256];
    } newProcess;

    // For system calls
    struct SysCall {
      int pid;
      char bc [256];
    } sysCall;
  } vals;

};
  
// Return values
const int SRET_SUCCESS             = 0;
const int SRET_NEW_PROCESS         = 1;
const int SRET_SYSCALL             = 2;
const int SRET_NO_PROCESSES        = 3;
const int SRET_NO_ACTIVE_PROCESSES = 4;
const int SRET_ERROR               = -1;

// Policy
const int ROUND_ROBIN = 0;
const int LOTTERY     = 1;

// Round-Robin TimeSlice
const int TIME_SLICE = 2;

class Scheduler {
 private:
   int RR_Time;
   int L_Tickets;
   queue<int> ActiveQueue;
   map<int,Process*> ActiveProcesses;
   map<int,Process*> WaitingProcesses;
   set<int> pidSet;
   int scheduling_policy; // 0 = round robin, 1 = lottery
   Process* currentProcess;
   int currentPid;
   int tempPid;
   
 public:
   Scheduler(int imode);
   SchedulerReturn run(int tick);
   SchedulerReturn runRR(int tick);
   SchedulerReturn runL(int tick);
   map<int,Process*> getActiveProcesses()
   {
     return ActiveProcesses;
   }
   map<int,Process*> getWaitingProcesses()
   {
     return WaitingProcesses;
   }   
   int AddProcess(int ipid,Process* p);
   int UnblockProcess(int ipid);
   int getPid();
   int switchProcesses();
};

#endif
